/**
*@Author: QWP
*@Description: websockt类封装
*@Date 2024-08-29 17:36
*/
import { ref, onUnmounted } from "vue";

interface WebSocketOptions {
  url: string;
  protocols?: string | string[];
  reconnectTimeout?: number;
}

let reConnectNumber: number = 0;
let timer: any = null;

class WebSocketService {
  private ws: WebSocket | null = null;
  private callbacks: { [key: string]: Function[] } = {};
  private reconnectTimeoutMs: number = 10000; // 默认30秒重连间隔
  private isRealClose: boolean = false;
  
  constructor(private options: WebSocketOptions) {}
  
  public open(): void {
    this.ws = new WebSocket(this.options.url, this.options.protocols);
    this.ws.addEventListener("open", this.handleOpen);
    this.ws.addEventListener("message", this.handleMessage);
    this.ws.addEventListener("error", this.handleError);
    this.ws.addEventListener("close", this.handleClose);
  }

  public close(isActiveClose: boolean = false): void {
    if (this.ws) {
      this.ws.close();
      this.isRealClose = isActiveClose
      if (!isActiveClose) {
        timer = setTimeout(() => this.reconnect(),  this.reconnectTimeoutMs);
      }
      else {
        clearTimeout(timer)
      }
    }
  }

  public reconnect(): void {
    reConnectNumber += 1;
    if(reConnectNumber <= 50) {
      this.open();
    }
    else {
      this.close(true)
      console.log("连接建立失败，已关闭....")
    }
  }

  public on(event: "message", callback: (data: any) => void): void;
  public on(event: "open" | "error" | "close", callback: () => void): void;
  public on(event: string, callback: (...args: any[]) => void): void {
    if (!this.callbacks[event]) {
      this.callbacks[event] = [];
    }
    this.callbacks[event].push(callback);
  }

  private handleOpen = (): void => {
    console.log("WebSocket连接已建立");
    reConnectNumber = 0;
    if(!timer) {
      clearTimeout(timer)
    }
    if (this.callbacks.open) {
      this.callbacks.open.forEach((cb) => cb());
    }
  };

  private handleMessage = (event: MessageEvent): void => {
    const data = JSON.parse(event.data);
    if (this.callbacks.message) {
      this.callbacks.message.forEach((cb) => cb(data));
    }
  };

  private handleError = (error: Event): void => {
    console.error("WebSocket错误:", error);
    if (this.callbacks.error) {
      this.callbacks.error.forEach((cb) => cb(error));
    }
  };

  private handleClose = (isActiveClose?: boolean): void => {
    console.log("🚀 ~ WebSocketService ~ isActiveClose:", isActiveClose)
    console.log("WebSocket连接已关闭");
    if (this.callbacks.close) {
      this.callbacks.close.forEach((cb) => cb());
      if(this.isRealClose == false) {
        if (!this.options.reconnectTimeout) {
          console.log("正在重进建立连接....")
          timer = setTimeout(() => this.reconnect(),  this.reconnectTimeoutMs);
        }
      }
    }
  };

  public send(data: any): void {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    } else {
      console.warn("尝试发送消息时WebSocket未连接");
    }
  }
}

export default function useWebSocket(options: WebSocketOptions) {
  const wsService = new WebSocketService(options);

  onUnmounted(() => {
    wsService.close(true);
  });

  return {
    open: wsService.open.bind(wsService),
    close: wsService.close.bind(wsService),
    reconnect: wsService.reconnect.bind(wsService),
    on: wsService.on.bind(wsService),
    send: wsService.send.bind(wsService),
  };
}